<template>
  <div class="min-h-screen py-8 px-4 sm:px-6 lg:px-8">
    <div class="max-w-7xl mx-auto">
      <!-- 页面标题 -->
      <div class="text-center mb-12">
        <h1 class="text-4xl font-bold mb-4 tech-text">Selection API</h1>
        <p class="text-gray-300 text-lg">
          操作和管理用户文本选择，实现高级文本交互功能
        </p>
      </div>

      <!-- 浏览器支持提示 -->
      <div v-if="!isSupported" class="tech-card mb-8 border-yellow-600">
        <div class="flex items-center mb-4">
          <i class="i-carbon-warning text-yellow-500 text-xl mr-3"></i>
          <h3 class="text-xl font-semibold text-yellow-500">浏览器支持提示</h3>
        </div>
        <p class="text-gray-300">
          您的浏览器不支持 Selection API。此功能需要现代浏览器支持。
        </p>
      </div>

      <!-- 基础选择信息 -->
      <div class="tech-card mb-8">
        <h2 class="text-2xl font-semibold mb-6 text-white">当前选择信息</h2>
        
        <div class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-6">
          <div class="bg-gray-800 rounded-lg p-4">
            <div class="text-gray-400 text-sm mb-1">选中文本</div>
            <div class="text-white text-xl font-semibold truncate" :title="selectedText">
              {{ selectedText || '-' }}
            </div>
          </div>

          <div class="bg-gray-800 rounded-lg p-4">
            <div class="text-gray-400 text-sm mb-1">字符数</div>
            <div class="text-white text-2xl font-semibold">
              {{ selectedText.length }}
            </div>
          </div>

          <div class="bg-gray-800 rounded-lg p-4">
            <div class="text-gray-400 text-sm mb-1">范围数量</div>
            <div class="text-white text-2xl font-semibold">
              {{ rangeCount }}
            </div>
          </div>

          <div class="bg-gray-800 rounded-lg p-4">
            <div class="text-gray-400 text-sm mb-1">是否折叠</div>
            <div class="text-white text-2xl font-semibold">
              {{ isCollapsed ? '是' : '否' }}
            </div>
          </div>
        </div>

        <div class="bg-gray-800 rounded-lg p-6">
          <h3 class="text-white font-semibold mb-4">选择演示文本</h3>
          <p
            ref="demoTextRef"
            class="text-gray-300 leading-relaxed select-text"
            @mouseup="updateSelection"
          >
            Selection API 是一个强大的浏览器 API，允许开发者获取和操作用户在页面上选择的文本。
            通过这个 API，我们可以实现诸如文本高亮、格式化工具、翻译助手等功能。
            选择这段文本来查看 Selection API 的实时信息。
            你可以选择任意部分，甚至可以跨越多个段落进行选择。
          </p>
        </div>
      </div>

      <!-- 选择操作 -->
      <div class="tech-card mb-8">
        <h2 class="text-2xl font-semibold mb-6 text-white">选择操作</h2>
        
        <div class="grid grid-cols-2 md:grid-cols-4 gap-3 mb-6">
          <button
            @click="selectAll"
            class="tech-button"
          >
            <i class="i-carbon-select-01 mr-2"></i>
            全选
          </button>

          <button
            @click="clearSelection"
            class="bg-red-600 hover:bg-red-700 text-white px-4 py-3 rounded-lg transition-colors"
          >
            <i class="i-carbon-close mr-2"></i>
            清除选择
          </button>

          <button
            @click="selectFirstWord"
            class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-3 rounded-lg transition-colors"
          >
            <i class="i-carbon-cursor-1 mr-2"></i>
            选择首词
          </button>

          <button
            @click="selectLastWord"
            class="bg-green-600 hover:bg-green-700 text-white px-4 py-3 rounded-lg transition-colors"
          >
            <i class="i-carbon-cursor-2 mr-2"></i>
            选择尾词
          </button>
        </div>

        <div class="grid grid-cols-2 md:grid-cols-4 gap-3">
          <button
            @click="extendToEnd"
            :disabled="!selectedText"
            class="bg-purple-600 hover:bg-purple-700 text-white px-4 py-3 rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
          >
            <i class="i-carbon-arrow-right mr-2"></i>
            扩展到末尾
          </button>

          <button
            @click="collapseToStart"
            :disabled="!selectedText"
            class="bg-orange-600 hover:bg-orange-700 text-white px-4 py-3 rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
          >
            <i class="i-carbon-chevron-left mr-2"></i>
            折叠到开始
          </button>

          <button
            @click="collapseToEnd"
            :disabled="!selectedText"
            class="bg-orange-600 hover:bg-orange-700 text-white px-4 py-3 rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
          >
            <i class="i-carbon-chevron-right mr-2"></i>
            折叠到结束
          </button>

          <button
            @click="deleteSelection"
            :disabled="!selectedText"
            class="bg-red-600 hover:bg-red-700 text-white px-4 py-3 rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
          >
            <i class="i-carbon-trash-can mr-2"></i>
            删除选中
          </button>
        </div>
      </div>

      <!-- 文本处理 -->
      <div class="tech-card mb-8">
        <h2 class="text-2xl font-semibold mb-6 text-white">文本处理</h2>
        
        <div class="bg-gray-800 rounded-lg p-6 mb-6">
          <div
            ref="editableTextRef"
            contenteditable="true"
            class="text-gray-300 leading-relaxed p-4 bg-gray-900 rounded-lg outline-none focus:ring-2 focus:ring-tech-accent min-h-[150px]"
            @mouseup="updateSelection"
            @keyup="updateSelection"
          >
            这是一个可编辑的文本区域。你可以在这里选择文本并应用各种格式和操作。
            尝试选择一些文本，然后使用下方的按钮进行操作。
          </div>
        </div>

        <div class="grid grid-cols-2 md:grid-cols-4 gap-3">
          <button
            @click="wrapWithTag('strong')"
            :disabled="!selectedText"
            class="tech-button disabled:opacity-50 disabled:cursor-not-allowed"
          >
            <i class="i-carbon-text-bold mr-2"></i>
            加粗
          </button>

          <button
            @click="wrapWithTag('em')"
            :disabled="!selectedText"
            class="tech-button disabled:opacity-50 disabled:cursor-not-allowed"
          >
            <i class="i-carbon-text-italic mr-2"></i>
            斜体
          </button>

          <button
            @click="wrapWithTag('mark')"
            :disabled="!selectedText"
            class="tech-button disabled:opacity-50 disabled:cursor-not-allowed"
          >
            <i class="i-carbon-highlight mr-2"></i>
            高亮
          </button>

          <button
            @click="replaceSelection"
            :disabled="!selectedText"
            class="tech-button disabled:opacity-50 disabled:cursor-not-allowed"
          >
            <i class="i-carbon-edit mr-2"></i>
            替换文本
          </button>
        </div>
      </div>

      <!-- 智能工具 -->
      <div class="tech-card mb-8">
        <h2 class="text-2xl font-semibold mb-6 text-white">智能工具</h2>
        
        <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
          <button
            @click="copyToClipboard"
            :disabled="!selectedText"
            class="bg-gray-800 hover:bg-gray-700 text-white p-6 rounded-lg transition-colors text-left disabled:opacity-50 disabled:cursor-not-allowed"
          >
            <i class="i-carbon-copy text-3xl text-blue-400 mb-3 block"></i>
            <div class="text-lg font-semibold mb-2">复制选中文本</div>
            <div class="text-gray-400 text-sm">将选中的文本复制到剪贴板</div>
          </button>

          <button
            @click="getWordCount"
            :disabled="!selectedText"
            class="bg-gray-800 hover:bg-gray-700 text-white p-6 rounded-lg transition-colors text-left disabled:opacity-50 disabled:cursor-not-allowed"
          >
            <i class="i-carbon-character-whole-number text-3xl text-green-400 mb-3 block"></i>
            <div class="text-lg font-semibold mb-2">词数统计</div>
            <div class="text-gray-400 text-sm">统计选中文本的词数和字符数</div>
          </button>

          <button
            @click="searchSelected"
            :disabled="!selectedText"
            class="bg-gray-800 hover:bg-gray-700 text-white p-6 rounded-lg transition-colors text-left disabled:opacity-50 disabled:cursor-not-allowed"
          >
            <i class="i-carbon-search text-3xl text-purple-400 mb-3 block"></i>
            <div class="text-lg font-semibold mb-2">搜索选中文本</div>
            <div class="text-gray-400 text-sm">在新标签页中搜索选中的内容</div>
          </button>

          <button
            @click="showSelectionInfo"
            :disabled="!selectedText"
            class="bg-gray-800 hover:bg-gray-700 text-white p-6 rounded-lg transition-colors text-left disabled:opacity-50 disabled:cursor-not-allowed"
          >
            <i class="i-carbon-information text-3xl text-yellow-400 mb-3 block"></i>
            <div class="text-lg font-semibold mb-2">详细信息</div>
            <div class="text-gray-400 text-sm">显示选择的详细技术信息</div>
          </button>
        </div>
      </div>

      <!-- 高级示例 -->
      <div class="tech-card mb-8">
        <h2 class="text-2xl font-semibold mb-6 text-white">高级示例：文本高亮器</h2>
        
        <div class="bg-gray-800 rounded-lg p-6 mb-4">
          <div
            ref="highlightTextRef"
            class="text-gray-300 leading-relaxed"
            @mouseup="handleHighlight"
          >
            <p class="mb-4">
              在这个区域中选择任何文本，它会自动被高亮显示。
              这是一个模拟真实应用场景的例子，比如 PDF 阅读器中的文本标注功能。
            </p>
            <p class="mb-4">
              Selection API 可以用于实现各种文本相关的功能：笔记应用、文本编辑器、
              协作工具、阅读器等。通过结合 Range API，可以实现更复杂的文本操作。
            </p>
            <p>
              尝试在这段文本中选择一些内容，看看会发生什么！
              你可以选择多次，创建多个高亮区域。
            </p>
          </div>
        </div>

        <button
          @click="clearHighlights"
          class="bg-red-600 hover:bg-red-700 text-white px-6 py-3 rounded-lg transition-colors"
        >
          <i class="i-carbon-clean mr-2"></i>
          清除所有高亮
        </button>
      </div>

      <!-- 选择历史 -->
      <div v-if="selectionHistory.length > 0" class="tech-card mb-8">
        <div class="flex justify-between items-center mb-6">
          <h2 class="text-2xl font-semibold text-white">选择历史</h2>
          <button
            @click="clearHistory"
            class="text-red-400 hover:text-red-300 text-sm"
          >
            <i class="i-carbon-clean mr-1"></i>
            清空历史
          </button>
        </div>

        <div class="space-y-2 max-h-64 overflow-y-auto">
          <div
            v-for="(item, index) in selectionHistory.slice().reverse()"
            :key="index"
            class="bg-gray-800 rounded-lg p-4"
          >
            <div class="flex justify-between items-start">
              <div class="flex-1">
                <div class="text-white font-medium mb-1">{{ item.text }}</div>
                <div class="text-gray-400 text-sm">
                  长度: {{ item.length }} 字符
                </div>
              </div>
              <div class="text-gray-400 text-xs">{{ item.timestamp }}</div>
            </div>
          </div>
        </div>
      </div>

      <!-- API 信息 -->
      <div class="tech-card">
        <h3 class="text-xl font-semibold mb-4 text-white">API 信息</h3>
        <div class="space-y-4 text-gray-300">
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">浏览器支持</h4>
            <p>所有现代浏览器都支持 Selection API</p>
          </div>
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">主要对象和方法</h4>
            <ul class="list-disc list-inside space-y-1">
              <li><code class="bg-gray-800 px-2 py-1 rounded">window.getSelection()</code> - 获取 Selection 对象</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">selection.toString()</code> - 获取选中的文本</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">selection.getRangeAt(index)</code> - 获取指定范围</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">selection.addRange(range)</code> - 添加范围</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">selection.removeAllRanges()</code> - 清除所有选择</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">selection.collapse(node, offset)</code> - 折叠选择</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">selection.extend(node, offset)</code> - 扩展选择</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">selection.selectAllChildren(node)</code> - 选择所有子节点</li>
            </ul>
          </div>
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">Selection 属性</h4>
            <ul class="list-disc list-inside space-y-1">
              <li><code class="bg-gray-800 px-2 py-1 rounded">anchorNode</code> - 选择起始节点</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">anchorOffset</code> - 起始偏移量</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">focusNode</code> - 选择结束节点</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">focusOffset</code> - 结束偏移量</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">isCollapsed</code> - 是否折叠（无选择）</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">rangeCount</code> - 范围数量</li>
            </ul>
          </div>
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">使用场景</h4>
            <ul class="list-disc list-inside space-y-1">
              <li>富文本编辑器（如 TinyMCE、Quill）</li>
              <li>文本高亮和标注工具</li>
              <li>PDF 阅读器的文本选择</li>
              <li>翻译工具和词典扩展</li>
              <li>文本分析和统计工具</li>
              <li>协作编辑和评论系统</li>
              <li>代码编辑器的选择功能</li>
            </ul>
          </div>
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">Range API</h4>
            <p class="text-sm leading-relaxed mb-2">
              Selection API 通常与 Range API 配合使用。Range 对象表示文档中的一个区域，
              可以精确控制选择的开始和结束位置。
            </p>
            <ul class="list-disc list-inside space-y-1 text-sm">
              <li><code class="bg-gray-800 px-1 rounded">range.setStart(node, offset)</code> - 设置起点</li>
              <li><code class="bg-gray-800 px-1 rounded">range.setEnd(node, offset)</code> - 设置终点</li>
              <li><code class="bg-gray-800 px-1 rounded">range.deleteContents()</code> - 删除内容</li>
              <li><code class="bg-gray-800 px-1 rounded">range.extractContents()</code> - 提取内容</li>
              <li><code class="bg-gray-800 px-1 rounded">range.cloneContents()</code> - 克隆内容</li>
            </ul>
          </div>
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">最佳实践</h4>
            <ul class="list-disc list-inside space-y-1 text-sm">
              <li>在操作前检查选择是否存在</li>
              <li>保存和恢复选择状态（如在异步操作后）</li>
              <li>处理跨元素选择的边界情况</li>
              <li>注意 contenteditable 元素中的特殊行为</li>
              <li>考虑移动设备的触摸选择</li>
            </ul>
          </div>
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">常见应用</h4>
            <div class="text-sm space-y-2">
              <p><strong>1. 自定义右键菜单：</strong>根据选中的文本显示相关操作</p>
              <p><strong>2. 文本格式化：</strong>对选中文本应用样式（加粗、斜体、颜色等）</p>
              <p><strong>3. 智能搜索：</strong>选中文本后快速搜索或翻译</p>
              <p><strong>4. 批注系统：</strong>选择文本并添加评论或笔记</p>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'

// 类型定义
interface SelectionHistoryItem {
  text: string
  length: number
  timestamp: string
}

// 响应式状态
const isSupported = ref(true)
const selectedText = ref('')
const rangeCount = ref(0)
const isCollapsed = ref(true)
const selectionHistory = ref<SelectionHistoryItem[]>([])

// 元素引用
const demoTextRef = ref<HTMLElement | null>(null)
const editableTextRef = ref<HTMLElement | null>(null)
const highlightTextRef = ref<HTMLElement | null>(null)

// 初始化
onMounted(() => {
  isSupported.value = !!window.getSelection
  document.addEventListener('selectionchange', updateSelection)
})

// 更新选择信息
const updateSelection = () => {
  const selection = window.getSelection()
  if (!selection) return

  selectedText.value = selection.toString()
  rangeCount.value = selection.rangeCount
  isCollapsed.value = selection.isCollapsed

  // 记录到历史（排除空选择）
  if (selectedText.value && selectedText.value.length > 0) {
    const isDuplicate = selectionHistory.value.some(
      item => item.text === selectedText.value && 
      Date.now() - new Date(item.timestamp).getTime() < 1000
    )
    
    if (!isDuplicate) {
      selectionHistory.value.push({
        text: selectedText.value,
        length: selectedText.value.length,
        timestamp: new Date().toLocaleString('zh-CN')
      })

      // 只保留最近 20 条
      if (selectionHistory.value.length > 20) {
        selectionHistory.value.shift()
      }
    }
  }
}

// 全选
const selectAll = () => {
  if (!demoTextRef.value) return
  
  const selection = window.getSelection()
  if (!selection) return

  const range = document.createRange()
  range.selectNodeContents(demoTextRef.value)
  selection.removeAllRanges()
  selection.addRange(range)
  
  updateSelection()
}

// 清除选择
const clearSelection = () => {
  const selection = window.getSelection()
  if (selection) {
    selection.removeAllRanges()
  }
  updateSelection()
}

// 选择首词
const selectFirstWord = () => {
  if (!demoTextRef.value) return
  
  const text = demoTextRef.value.textContent || ''
  const firstWord = text.match(/\S+/)
  
  if (firstWord) {
    const range = document.createRange()
    const textNode = demoTextRef.value.firstChild
    if (textNode) {
      range.setStart(textNode, 0)
      range.setEnd(textNode, firstWord[0].length)
      
      const selection = window.getSelection()
      if (selection) {
        selection.removeAllRanges()
        selection.addRange(range)
      }
    }
  }
  
  updateSelection()
}

// 选择尾词
const selectLastWord = () => {
  if (!demoTextRef.value) return
  
  const text = demoTextRef.value.textContent || ''
  const words = text.match(/\S+/g)
  
  if (words && words.length > 0) {
    const lastWord = words[words.length - 1]
    const lastWordIndex = text.lastIndexOf(lastWord)
    
    const range = document.createRange()
    const textNode = demoTextRef.value.firstChild
    if (textNode) {
      range.setStart(textNode, lastWordIndex)
      range.setEnd(textNode, lastWordIndex + lastWord.length)
      
      const selection = window.getSelection()
      if (selection) {
        selection.removeAllRanges()
        selection.addRange(range)
      }
    }
  }
  
  updateSelection()
}

// 扩展到末尾
const extendToEnd = () => {
  if (!demoTextRef.value) return
  
  const selection = window.getSelection()
  if (!selection || selection.rangeCount === 0) return
  
  const textNode = demoTextRef.value.firstChild
  if (textNode && textNode.textContent) {
    selection.extend(textNode, textNode.textContent.length)
  }
  
  updateSelection()
}

// 折叠到开始
const collapseToStart = () => {
  const selection = window.getSelection()
  if (selection) {
    selection.collapseToStart()
  }
  updateSelection()
}

// 折叠到结束
const collapseToEnd = () => {
  const selection = window.getSelection()
  if (selection) {
    selection.collapseToEnd()
  }
  updateSelection()
}

// 删除选中文本
const deleteSelection = () => {
  const selection = window.getSelection()
  if (!selection || selection.rangeCount === 0) return
  
  const range = selection.getRangeAt(0)
  range.deleteContents()
  
  updateSelection()
}

// 包裹标签
const wrapWithTag = (tagName: string) => {
  const selection = window.getSelection()
  if (!selection || selection.rangeCount === 0) return
  
  const range = selection.getRangeAt(0)
  const selectedContent = range.extractContents()
  
  const wrapper = document.createElement(tagName)
  wrapper.appendChild(selectedContent)
  range.insertNode(wrapper)
  
  // 重新选择包裹后的内容
  range.selectNodeContents(wrapper)
  selection.removeAllRanges()
  selection.addRange(range)
  
  updateSelection()
}

// 替换选中文本
const replaceSelection = () => {
  const newText = prompt('输入新文本:', selectedText.value)
  if (newText === null) return
  
  const selection = window.getSelection()
  if (!selection || selection.rangeCount === 0) return
  
  const range = selection.getRangeAt(0)
  range.deleteContents()
  range.insertNode(document.createTextNode(newText))
  
  updateSelection()
}

// 复制到剪贴板
const copyToClipboard = async () => {
  try {
    await navigator.clipboard.writeText(selectedText.value)
    alert('已复制到剪贴板！')
  } catch (err) {
    console.error('复制失败:', err)
    alert('复制失败')
  }
}

// 词数统计
const getWordCount = () => {
  const words = selectedText.value.match(/\S+/g)
  const wordCount = words ? words.length : 0
  const charCount = selectedText.value.length
  
  alert(`词数: ${wordCount}\n字符数: ${charCount}`)
}

// 搜索选中文本
const searchSelected = () => {
  const searchUrl = `https://www.google.com/search?q=${encodeURIComponent(selectedText.value)}`
  window.open(searchUrl, '_blank')
}

// 显示详细信息
const showSelectionInfo = () => {
  const selection = window.getSelection()
  if (!selection) return
  
  const info = `
选中文本: ${selectedText.value}
字符数: ${selectedText.value.length}
范围数量: ${selection.rangeCount}
是否折叠: ${selection.isCollapsed}
锚点节点: ${selection.anchorNode?.nodeName}
焦点节点: ${selection.focusNode?.nodeName}
  `.trim()
  
  alert(info)
}

// 处理高亮
const handleHighlight = () => {
  const selection = window.getSelection()
  if (!selection || selection.isCollapsed) return
  
  const range = selection.getRangeAt(0)
  const selectedContent = range.extractContents()
  
  const mark = document.createElement('mark')
  mark.className = 'bg-yellow-300 text-black'
  mark.appendChild(selectedContent)
  range.insertNode(mark)
  
  // 清除选择
  selection.removeAllRanges()
}

// 清除所有高亮
const clearHighlights = () => {
  if (!highlightTextRef.value) return
  
  const marks = highlightTextRef.value.querySelectorAll('mark')
  marks.forEach(mark => {
    const parent = mark.parentNode
    if (parent) {
      while (mark.firstChild) {
        parent.insertBefore(mark.firstChild, mark)
      }
      parent.removeChild(mark)
    }
  })
}

// 清空历史
const clearHistory = () => {
  selectionHistory.value = []
}
</script>

<style scoped>
mark {
  background-color: #fef08a;
  color: #000;
  padding: 2px 4px;
  border-radius: 2px;
}
</style>

